﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using Newtonsoft.Json;

namespace LuaMemCheck
{
    public partial class LuaMemCheckForm : Form
    {
        private string _rootDirectoryPath = @"D:\SnapLog\origin";

        private bool _sort = false;
        private List<LuaObject> _currentLuaObjects = new List<LuaObject>();
        private SnapInfo _curSnapInfo;
        private LuaInfoListControl _luaInfoListControl;


        public LuaMemCheckForm()
        {
            InitializeComponent();
            this.WindowState = FormWindowState.Maximized;
        }

        private void LuaMemCheckForm_Load(object sender, EventArgs e)
        {

            _luaInfoListControl = new LuaInfoListControl(LuaInfoList);

            RefreshUI();
        }

        private void RefreshUI()
        {
            ShowFileListAndInit();

//            SelectDefaultFile();
        }


        private void SelectDefaultFile()
        {
            FileList.SelectedNode = FileList.Nodes[FileList.Nodes.Count - 1];
            FileList.Focus();
        }


        private string GetLatePath()
        {
            string configFilePath = Path.Combine(Directory.GetCurrentDirectory(), "path.txt");
            if (File.Exists(configFilePath))
            {
                string path = File.ReadAllText(configFilePath);
                if (!string.IsNullOrEmpty(path))
                {
                    return path;
                }
            }
            return @"D:\SnapLog\origin";
        }

        private void ShowFileListAndInit()
        {
            //tree
            BrowseTxt.Text = GetLatePath();

            FileList.Nodes.Clear();
            FileList.CheckBoxes = true;
            SnapInfoMgr.Instance.Clear();
            DirectoryInfo root = new DirectoryInfo(GetLatePath());
            FileInfo[] files = root.GetFiles();
            foreach (var fileInfo in files)
            {
                TreeNode treeNode = new TreeNode(fileInfo.Name);
                treeNode.Name = fileInfo.Name;
                FileList.Nodes.Add(treeNode);
                CreateSnapInfoByPath(fileInfo.FullName);
            }
            FileList.HideSelection = false;

        }

        private void ShowLuaInfoList()
        {

            _luaInfoListControl.SetLuaObjects(_currentLuaObjects);

        }

        private void CreateSnapInfoByPath(string path)
        {

            string h = File.ReadAllText(path);
            JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
            serializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
            serializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
            DebugData t = JsonConvert.DeserializeObject<DebugData>(h, serializerSettings);

            SnapInfo snapInfo = new SnapInfo(t);
            SnapInfoMgr.Instance.AddSnapInfo(snapInfo);

        }

        private void FileList_AfterSelect(object sender, TreeViewEventArgs e)
        {
            SnapInfoMgr.Instance.SetCurrentIndex(FileList.SelectedNode.Index);
            _curSnapInfo = SnapInfoMgr.Instance.GetSnapInfoByIndex(FileList.SelectedNode.Index);
            _currentLuaObjects = _curSnapInfo.GetBFS();

            GlobalInfo globalInfo = _curSnapInfo.GetDebugData().MyGlobalInfo;
            string info =
                string.Format(
                    "TableCount : {0}\r\nTableSize : {1}\r\nFuncCount : {2}\r\nFuncsize : {3}\r\nStringCount : {4}\r\nStringSize : {5}\r\nProtoCount : {6}\r\nProtoSize : {7}\r\nOtherCount : {8}\r\n",
                    globalInfo.TableCount,
                    globalInfo.TableSize,
                    globalInfo.FuncCount,
                    globalInfo.FuncSize,
                    globalInfo.StrCount,
                    globalInfo.StrSize,
                    globalInfo.ProtoCount,
                    globalInfo.ProtoSize,
                    globalInfo.OtherCount
                    );
            GlobalInfoTxt.Text = info;
        }

        private void LuaInfoList_ItemMouseHover(object sender, ListViewItemMouseHoverEventArgs e)
        {
            ToolTip toolTip = new ToolTip();
            string itemInfor = e.Item.SubItems[2].Text + "\n";
            toolTip.SetToolTip(e.Item.ListView, itemInfor);
        }

        private void LeakBtn_Click(object sender, EventArgs e)
        {
            LeakSnapContainer leakSnapContainer = new LeakSnapContainer();
            for (int i = 0; i < FileList.Nodes.Count; i++)
            {
                if (FileList.Nodes[i].Checked)
                {
                    leakSnapContainer.Add(SnapInfoMgr.Instance.GetSnapInfoByIndex(i));
                }
            }
            LeakForm _leakForm = new LeakForm();
            _leakForm.SetLeakLuaObjects(leakSnapContainer.GenerateLeakLuaObjects());
            _leakForm.Show();
            
        }

        private void BrowseBtn_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog();
            dialog.Description = "请选择leak文件夹";
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                if (!string.IsNullOrEmpty(dialog.SelectedPath))
                {
                    BrowseTxt.Text = dialog.SelectedPath;
                    File.WriteAllText(Path.Combine(Directory.GetCurrentDirectory(), "path.txt"), BrowseTxt.Text);
                    RefreshUI();

                }
            }
        }

        private void FileList_AfterCheck(object sender, TreeViewEventArgs e)
        {
            
        }

        private void ShowDetailBtn_Click(object sender, EventArgs e)
        {
            ShowLuaInfoList();
        }

        private void LuaInfoList_MouseClick(object sender, MouseEventArgs e)
        {
            //禁止多选
//            LuaInfoList.MultiSelect = false;
            //鼠标右键
//            if (e.Button == MouseButtons.Right)
//            {
//                Point p = new Point(e.X, e.Y);
//                LuaInfoMenuStrip.Show(LuaInfoList, p);
//            }
        }

        private void LuaDetailToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var selectedItem = this.LuaInfoList.SelectedItems[0];
            LuaObjectDetail luaObjectDetailForm = new LuaObjectDetail();
            luaObjectDetailForm.SetLuaObject(_curSnapInfo.GetLuaObject(selectedItem.SubItems[1].Text),_curSnapInfo);
            luaObjectDetailForm.Show();
        }
    }

    public class ListViewItemComparer : IComparer
    {
        protected SortOrder _order = SortOrder.Ascending;
        protected int _col;


        public ListViewItemComparer(int column)
        {
            _col = column;
        }

        public void ChangeSortOrder()
        {
            if (_order == SortOrder.Ascending)
            {
                _order = SortOrder.Descending;
            }
            else if(_order == SortOrder.Descending)
            {
                _order = SortOrder.Ascending;
            }
        }

        public virtual int Compare(object x, object y)
        {
            return 0;
        }
    }

    public class ListViewStringComparer : ListViewItemComparer
    {
        public ListViewStringComparer(int column):base(column)
        {
            
        }

        public override int Compare(object x, object y)
        {
            if (_order == SortOrder.Ascending)
                return String.Compare(((ListViewItem)x).SubItems[_col].Text, ((ListViewItem)y).SubItems[_col].Text);
            return -String.Compare(((ListViewItem)x).SubItems[_col].Text, ((ListViewItem)y).SubItems[_col].Text);
        }
    }

    public class ListViewDoubleComparer : ListViewItemComparer
    {
        public ListViewDoubleComparer(int column):base(column)
        {

        }

        public override int Compare(object x, object y)
        {
            bool isLess = Convert.ToDouble(((ListViewItem) x).SubItems[_col].Text) <
                          Convert.ToDouble(((ListViewItem) y).SubItems[_col].Text);
            if (_order == SortOrder.Ascending)
                return isLess ? 1 : -1;
            return isLess ? -1 : 1;

        }
    }

}
